<?php

namespace app\api\controller;

use app\api\model\CouponCategory;
use app\api\model\CouponOrder;
use app\api\model\Coupons;
use app\api\model\CouponVip;
use app\api\model\OrderVip;
use app\api\model\UserCoupons;
use app\api\model\Users;
use app\api\model\UserVip;
use app\api\model\Wechat;
use app\common\controller\Api;
use think\Controller;
use think\Db;
use think\Request;
use Yansongda\Pay\Exceptions\GatewayException;

class Coupon extends Api
{
    protected $noNeedLogin = ['paymentResult', 'pay'];
    protected $noNeedRight = ['*'];
    /**
     * 优惠券分类
     */
    public function category()
    {
        $categories = CouponCategory::getCategories();
        $categories ? $this->success('请求成功', compact('categories')) : $this->error('没有数据');
    }

    /**
     * 优惠券列表
     */
    public function index()
    {
        $category_id = $this->request->get('category_id');
        $length = $this->request->get('length');
        $coupons = Coupons::getByCategoryId($category_id, $length);
        if (!$coupons) {
            $this->error('没有数据', [], 2);
        }
        $vips = UserVip::getVipIds();
        foreach ($coupons as $val) {
            $user_id = $this->auth->getUserId();
            $count = UserCoupons::getCountByCouponId($user_id, $val['id']);
            $val['is_buy'] = $val->buy_num ? ($val->buy_num - $count > 0 ? true : false) : true;
            $val['vip_money'] = number_format($val['money'] * Users::getVipDiscount($user_id), 2);
            //会员专享
            $user_vips = array_column($val['vip'], 'id');
            $val['full_vip'] = array_diff($vips, $user_vips) ? false : true;
        }
        $this->success('请求成功', compact('coupons'));
    }

    /**
     * 优惠券详情
     */
    public function read($coupon_id)
    {
        $coupon = Coupons::with('vip')->find($coupon_id);
        $user_id = $this->auth->getUserId();
        $count = UserCoupons::getCountByCouponId($user_id, $coupon_id);
        $coupon['is_buy'] = $coupon->buy_num ? ($coupon->buy_num - $count > 0 ? true : false) : true;
        $coupon['vip_money'] = number_format($coupon['money'] * Users::getVipDiscount($user_id), 2);
        $vips = UserVip::getVipIds();
        $user_vips = array_column($coupon->vip, 'id');
        $val['full_vip'] = array_diff($vips, $user_vips) ? false : true;
        $coupon ? $this->success('请求成功', compact('coupon')) : $this->error('没有数据', [], 2);
    }

    /**
     * 优惠券支付
     */
    public function pay($coupon_id, Wechat $wechat)
    {
        $type = $this->request->post('type');
        $user = Users::with('userVip')->find($this->auth->getUserId());
        $coupon = Coupons::find($coupon_id);
        if (!$coupon) {
            $this->error('优惠券不存在');
        }
        if (!$user) {
            $this->error('用户不存在');
        }
        if (!$coupon->stock_num || $coupon->stock_num < $coupon->num) {
            $this->error('优惠券暂无库存');
        }
        $count = UserCoupons::getCountByCouponId($user->id, $coupon_id);
        if ($coupon->buy_num && $count >= $coupon->buy_num) {
            $this->error('每人限购'.$coupon->buy_num.'张');
        }
        //会员专享
        $coupon_vip = CouponVip::getUserVips($coupon_id);
        $user_vip = OrderVip::getUserVipIds($user->id);
        if ($coupon_vip && !array_intersect($user_vip, $coupon_vip)) {
            $this->error('此为会员专享优惠券，请先开通会员');
        }
        //会员折扣
        $discount = Users::getVipDiscount($this->auth->getUserId(), true);
        $order_no = 'C'.date('YmdHis').mt_rand(100, 999);
        $data = [
            'order_no' => $order_no,
            'user_id' => $user->id,
            'coupon_id' => $coupon_id,
            'total_amount' => $coupon->money * $discount,
            'createtime' => time(),
            'updatetime' => time()
        ];
        $order = CouponOrder::create($data);
        if ($coupon->money > 0) {
            //购买
            switch ($type) {
                //余额支付
                case 1:
                    if ($user->money < $coupon->money) {
                        $this->error('账号余额不足');
                    }
                    $this->paySuccess($order, $user, $coupon, 'account');
                    break;
                //微信
                case 2:
                    try {
                        $res = $wechat->miniapp($order, $user->openid, config('wechat.notify_url'));
                    } catch (\Exception $e) {
                        throw new GatewayException($e->getMessage(), $e->getCode());
                    }
                    $res['order_no'] = $order_no;
                    isset($e) ? $this->error('支付失败，请联系管理员') : $this->success('请求成功', $res);
                    break;
                default:
                    $this->error('支付类型无效');
                    break;
            }
        } else {
            //免费领取
            $this->paySuccess($order, $user, $coupon, 'free');
        }

    }

    /**
     * 支付回调
     */
    public function notify(Wechat $wechat)
    {
        $order_no = $this->request->post('order_no');
        if (empty($order_no)) {
            $this->error('订单号不能为空');
        }
        $order = CouponOrder::getByOrderNo($order_no);
        if (!$order) {
            $this->error('订单不存在');
        }
        if ($order->status) {
            $this->success('支付成功', ['order_id' => $order->id]);
        }
        //查询支付结果
        $res = $wechat->find($order_no);
        if ($res['return_code'] === 'SUCCESS' && $res['result_code'] === 'SUCCESS') {
            if ($res['trade_state'] === 'SUCCESS') {
                $coupon = Coupons::find($order['coupon_id']);
                $user = Users::find($order['user_id']);
                $this->paySuccess($order, $user, $coupon, 'wechat');
            } else {
                $this->error($res['trade_state_desc'], [], $res['trade_state']);
            }
        } else {
            $this->error('支付失败，请联系管理员');
        }

    }

    /**
     * 支付结果通知
     */
    public function paymentResult(Wechat $wechat)
    {
        $res = $wechat->verify();
        if ($res['return_code'] === 'SUCCESS' && $res['result_code'] === 'SUCCESS') {
            $order = OrderVip::getByOrderNo($res['out_trade_no']);
            if ($order && $order->status == 0) {
                $coupon = Coupons::find($order['coupon_id']);
                $user = Users::find($order['user_id']);
                $this->paySuccess($order, $user, $coupon, 'wechat');
            }
        }
        $wechat->wechatPay()->success()->send();
    }


    private function paySuccess($order, $user, $coupon, $type)
    {
        Db::startTrans();
        try {
            //更新订单信息
            $order->type = $type;
            $order->status = 1;
            $order->save();
            //余额支付
            $user->expense_money += $order['total_amount'];
            if ($type == 'account') {
                $user->money -= $order['total_amount'];
            }
            $user->save();
            //增加用户优惠券
            for ($i = 0; $i < $coupon->num; $i++) {
                UserCoupons::createUserCoupon($order->user_id, $coupon);
            }
            //更新剩余库存
            $stockNum = $coupon->stock_num - $coupon->num;
            $coupon->stock_num = $stockNum > 0 ? $stockNum : 0;
            $coupon->save();

            Db::commit();
        } catch (\Exception $e) {
            Db::rollback();
        }
        isset($e) ? $this->error($e->getMessage()) : $this->success('支付成功', ['order_id' => $order->id]);
    }

    /**
     * 优惠券赠送
     */
    public function share($share_user_id = 0, $user_coupon_id = 0)
    {
        $user_coupon = UserCoupons::find($user_coupon_id);
        if (!$user_coupon) {
            $this->error('优惠券不存在');
        }
        if ($user_coupon->status != 1) {
            $this->error('优惠券已过期或已使用');
        }
        if ($user_coupon->user_id != $share_user_id) {
            $this->error('此优惠券不属于该用户，无法领取');
        }
        $user_coupon->user_id = $this->auth->getUserId();
        $result = $user_coupon->save();
        $result ? $this->success('请求成功') : $this->error('领取失败');
    }

}
